package mplayer;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.util.Vector;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JSlider;
import javax.swing.JTextField;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import org.json.simple.JSONObject;

public class Gui extends JFrame {
	private static final long serialVersionUID = 1L;
	private Player player_;
	private Vector<File> playlist_;
	private JPanel jpcontrols_;
	private KListener keylistener_;
	private JSlider jsseek_;
	private JLabel jltime_;
	private ApiDemo api_;
	private boolean uploadingSongs_;
	
	public Gui(Player player) {
		keylistener_ 	= new KListener();
		playlist_ 		= new Vector<File>();
		uploadingSongs_ = false;
		this.player_ 	= player;
		initGui();
		enableControls(false);
	}
	
	private void initGui() {
		// Menu
		JMenuBar jmbmenu 	= new JMenuBar();
		JMenu jmfile 		= new JMenu("File");
		JMenu jmmyms		= new JMenu("MyMS");
		JMenu jmhelp		= new JMenu("Help");
		JMenuItem jmiopen	= new JMenuItem("Open file");
		JMenuItem jmiexit	= new JMenuItem("Exit");
		JMenuItem jmihelp	= new JMenuItem("Help");
		JMenuItem jmisetup 	= new JMenuItem("Settings");
		JMenuItem jmitogm	= new JMenuItem("Toggle on / off");
		jmfile.add(jmiopen);
		jmfile.add(jmiexit);
		jmhelp.add(jmihelp);
		jmmyms.add(jmisetup);
		jmmyms.add(jmitogm);
		jmbmenu.add(jmfile);
		jmbmenu.add(jmmyms);
		jmbmenu.add(jmhelp);
		
		// Layout
		jpcontrols_		= new JPanel(new BorderLayout());
		JPanel jpbuttons 		= new JPanel(new FlowLayout(FlowLayout.LEFT));
		jsseek_	= new JSlider();
		final JSlider jsvolume	= new JSlider();
		
		jsseek_.setValue(0);
		jsseek_.setMinimum(0);
		jsseek_.setMaximum(100);
		jsvolume.setValue(50);
		jsvolume.setMinimum(0);
		jsvolume.setMaximum(100);
		
		JButton jbprev 		= new JButton("Prev");
		JButton jbpause 	= new JButton("Pause");
		JButton jbstop		= new JButton("Stop");
		JButton jbmute		= new JButton("Mute");
		JButton jbnext 		= new JButton("Next");
		
		jbprev	.setPreferredSize(new Dimension(50, 20));
		jbpause	.setPreferredSize(new Dimension(50, 20));
		jbstop	.setPreferredSize(new Dimension(50, 20));
		jbmute	.setPreferredSize(new Dimension(50, 20));
		jsvolume.setPreferredSize(new Dimension(120, 20));
		jbnext	.setPreferredSize(new Dimension(50, 20));
		
		jltime_ 		= new JLabel("00:00/00.00");
		
		jpbuttons.add(jltime_);
		jpbuttons.add(jbprev);
		jpbuttons.add(jbpause);
		jpbuttons.add(jbstop);
		jpbuttons.add(jbnext);
		jpbuttons.add(jsvolume);
		jpbuttons.add(jbmute);
		
		jpcontrols_.add(jsseek_, BorderLayout.PAGE_START);
		jpcontrols_.add(jpbuttons, BorderLayout.PAGE_END);
		
		JPanel jpvideo = new JPanel();
		this.getContentPane().add(jpvideo, BorderLayout.CENTER);
		this.getContentPane().add(jpcontrols_, BorderLayout.PAGE_END);
		this.setJMenuBar(jmbmenu);
		this.setTitle("MyMS Media Player");
		this.pack();
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		this.setVisible(true);
		
		/* LISTENERS */
		
		// MENU
		jmisetup.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openMymsSettingsWindow();
			}
		});
		
		jmitogm.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				toggleUpload();
			}
		});
		
		jmiopen.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				openFileBrowser();
			}
		});
		
		jmiexit.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		
		jmihelp.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				// help menu
			}
		});
		
		// Buttons
		jbprev.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				playPrevious();
			}
		});
		
		jbpause.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				pause();
			}
		});
		
		jbstop.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				stop();
			}
		});
		
		jbnext.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				playNext();
			}
		});
		
		jbmute.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				mute();
			}
		});
		
		// Sliders
		jsseek_.addMouseListener(new MouseListener() {
			public void mouseReleased(MouseEvent e) {
				// Avoiding division by zero.
				if (jsseek_.getWidth() == 0) {
					return;
				}
				Point mouse 	= e.getPoint();
				Double percent 	= (double) mouse.x / (double) jsseek_.getWidth();
				player_.seek(percent);
			}
			public void mousePressed(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseClicked(MouseEvent e) {}
		});
		
		jsvolume.addMouseListener(new MouseListener() {
			public void mouseClicked(MouseEvent e) {}
			public void mouseEntered(MouseEvent e) {}
			public void mouseExited(MouseEvent e) {}
			public void mousePressed(MouseEvent e) {}
			public void mouseReleased(MouseEvent e) {
				// Avoiding division by zero.
				if(jsvolume.getWidth() == 0) {
					return;
				}

				Point mouse = e.getPoint();
				double percent = ((double) mouse.x/(double) jsvolume.getWidth())*100;
				player_.setVolume((int)percent);
			}
		});
		
		// Keylistener
		this.addKeyListener(keylistener_);
	}
	
	private void timeController() {
		Thread task = new Thread() {
			public void run() {
				while(true) {
					try {
						long position = player_.getQueryPos();
						long duration = player_.getQueryDur();

						jsseek_.setValue((int) ((position*100)/duration));

						int intCurMin = (int) (position/60);
						String curMin = null;
						if (intCurMin < 10) {
							curMin = "0" + intCurMin;
						} else {
							curMin = "" + intCurMin;
						}

						int intCurSec = (int) (position - (60*intCurMin));
						String curSec = null;
						if (intCurSec < 10) {
							curSec = "0" + intCurSec;
						} else {
							curSec = "" + intCurSec;
						}

						int intMaxMin = (int) (duration/60);
						String maxMin = null;
						if (intMaxMin < 9) {
							maxMin = "0" + intMaxMin;
						} else {
							maxMin = "" + intMaxMin;
						}

						int intMaxSec = (int) (duration - (60*intMaxMin));
						String maxSec = null;
						if (intMaxSec < 9) {
							maxSec = "0" + intMaxSec;
						} else {
							maxSec = "" + intMaxSec;
						}
						
						jltime_.setText(curMin + ":" + curSec + "/" + maxMin + ":" + maxSec);
						
						//
						
						if (position == 5) {
							if(uploadingSongs_) {
								uploadSong();
							}
						}
					} catch(Exception e) {}

					try {
						Thread.sleep(100);
					} catch(Exception e) {}
				}
			}
		};
		task.start();
	}
	
	private void enableControls(boolean b) {
		for (int i = 0; i < jpcontrols_.getComponentCount(); i++) {
			Component c = jpcontrols_.getComponent(i);
			if (c instanceof JPanel) {
				for (int j = 0; j < ((JPanel) c).getComponentCount(); j++) {
					((JPanel) c).getComponent(j).setEnabled(b);
				}
			} else {
				jpcontrols_.getComponent(i).setEnabled(b);
			}
		}
	}
	
	private void playPrevious() {
		// Fix when playlist is working!
	}
	
	private void pause() {
		player_.pause();
	}
	
	private void stop() {
		player_.stop();
		enableControls(false);
	}
	
	private void playNext() {
		// Fix when playlist is working!
	}
	
	private void mute() {
		player_.mute();
	}
	
	private void openFileBrowser() {
		JFileChooser fileopen = new JFileChooser();
		FileFilter filter = new FileNameExtensionFilter(".MP3", "mp3");
		fileopen.addChoosableFileFilter(filter);
		int ret = fileopen.showDialog(new JPanel(), "Open file");

		if (ret == JFileChooser.APPROVE_OPTION) {
			File file = fileopen.getSelectedFile();
			playFile(file);
		}
	}

	private void playFile(File f) {
		player_.playFile(f);
		timeController();
		enableControls(true);
	}
	
	// new shit
	private void openMymsSettingsWindow() {
		final JFrame f 				= new JFrame();
		JButton jbsave				= new JButton("Save settings");
		JButton jbcancel 			= new JButton("Cancel");
		final JTextField jtuser		= new JTextField(20);
		final JPasswordField jtpwd	= new JPasswordField(20);
		JLabel jlusername 		= new JLabel("Username: ");
		JLabel jlpwd 			= new JLabel("Password: ");
		
		JPanel mid = new JPanel();
		mid.setLayout(new BoxLayout(mid, BoxLayout.Y_AXIS));
		JPanel bot = new JPanel(new FlowLayout());
		bot.add(jbsave);
		bot.add(jbcancel);
		jlusername.setLabelFor(jtuser);
		jlpwd.setLabelFor(jtpwd);
		mid.add(jlusername);
		mid.add(jtuser);
		mid.add(jlpwd);
		mid.add(jtpwd);
		
		jbsave.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				initApi(jtuser.getText(), jtpwd.getText());
				f.dispose();
			}
		});
		
		jbcancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				f.dispose();
			}
		});
	
		f.getContentPane().add(mid, BorderLayout.CENTER);
		f.getContentPane().add(bot, BorderLayout.SOUTH);
		f.setTitle("MyMS Settings");
		f.setResizable(false);
		f.pack();
		f.setVisible(true);
	}
	private void initApi(String username, String password) {
		//System.out.println(username);
		//System.out.println(password);
		api_ = new ApiDemo(username, password, null);
	}
	
	private void uploadSong() {
		toggleUpload();
		JSONObject songinfo = player_.getTags();
		String artist 	= (String) songinfo.get("artist");
		String title 	= (String) songinfo.get("title");
		String album 	= (String) songinfo.get("album");
		String genre 	= (String) songinfo.get("genre");
		api_.uploadSong(artist, title, album, genre);
	}
	
	private void toggleUpload() {
		uploadingSongs_ = !uploadingSongs_;
	}
	
	private class KListener implements KeyListener {
		public void keyPressed(KeyEvent e) {
			int kc = e.getKeyChar();
			switch (kc) {
			case KeyEvent.VK_SPACE:
				pause();
				break;
			case 112: // p
			case KeyEvent.VK_P:
				break;
			case 102: // f
			case KeyEvent.VK_F:
				break;
			case 109: // m
			case KeyEvent.VK_M:
				mute();
				break;
			default:
				break;
			}
		}
		public void keyReleased(KeyEvent e) {}
		public void keyTyped(KeyEvent e) {}
	}
}
